<?php
/**
 * 代码高亮处理类
 * 替代 tempest/highlight 包的功能
 */

namespace app\common\library;

class CodeHighlighter
{
    /**
     * 简单的代码高亮处理
     * @param string $code 代码内容
     * @param string $language 编程语言
     * @return string 高亮后的HTML代码
     */
    public static function highlight($code, $language = 'php')
    {
        // 移除代码前后的空白字符
        $code = trim($code);
        
        // 转义HTML特殊字符
        $code = htmlspecialchars($code);
        
        // 简单的关键字高亮处理
        switch (strtolower($language)) {
            case 'php':
                $code = self::highlightPhp($code);
                break;
            case 'javascript':
            case 'js':
                $code = self::highlightJavaScript($code);
                break;
            case 'html':
                $code = self::highlightHtml($code);
                break;
            case 'css':
                $code = self::highlightCss($code);
                break;
            case 'python':
            case 'py':
                $code = self::highlightPython($code);
                break;
            default:
                // 不进行特殊处理
                break;
        }
        
        // 包装在pre和code标签中
        return '<pre><code class="language-' . htmlspecialchars($language) . '">' . $code . '</code></pre>';
    }
    
    /**
     * PHP代码高亮
     * @param string $code PHP代码
     * @return string 高亮后的代码
     */
    private static function highlightPhp($code)
    {
        // PHP关键字
        $keywords = [
            'abstract', 'and', 'array', 'as', 'break', 'callable', 'case', 'catch', 'class', 'clone',
            'const', 'continue', 'declare', 'default', 'die', 'do', 'echo', 'else', 'elseif', 'empty',
            'enddeclare', 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile', 'eval', 'exit',
            'extends', 'final', 'finally', 'for', 'foreach', 'function', 'global', 'goto', 'if',
            'implements', 'include', 'include_once', 'instanceof', 'insteadof', 'interface', 'isset',
            'list', 'namespace', 'new', 'or', 'print', 'private', 'protected', 'public', 'require',
            'require_once', 'return', 'static', 'switch', 'throw', 'trait', 'try', 'unset', 'use',
            'var', 'while', 'xor', 'yield'
        ];
        
        // 将关键字包装在<span>标签中
        foreach ($keywords as $keyword) {
            $code = preg_replace(
                '/\b(' . preg_quote($keyword) . ')\b/i',
                '<span class="keyword">$1</span>',
                $code
            );
        }
        
        // 字符串处理
        $code = preg_replace(
            '/(".*?")|(\'.*?\')/',
            '<span class="string">$1$2</span>',
            $code
        );
        
        // 注释处理
        $code = preg_replace(
            '/(\/\/.*$)|(\/\*.*?\*\/)/m',
            '<span class="comment">$1$2</span>',
            $code
        );
        
        return $code;
    }
    
    /**
     * JavaScript代码高亮
     * @param string $code JavaScript代码
     * @return string 高亮后的代码
     */
    private static function highlightJavaScript($code)
    {
        // JavaScript关键字
        $keywords = [
            'abstract', 'arguments', 'await', 'boolean', 'break', 'byte', 'case', 'catch', 'char',
            'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do', 'double', 'else',
            'enum', 'eval', 'export', 'extends', 'false', 'final', 'finally', 'float', 'for',
            'function', 'goto', 'if', 'implements', 'import', 'in', 'instanceof', 'int', 'interface',
            'let', 'long', 'native', 'new', 'null', 'package', 'private', 'protected', 'public',
            'return', 'short', 'static', 'super', 'switch', 'synchronized', 'this', 'throw', 'throws',
            'transient', 'true', 'try', 'typeof', 'var', 'void', 'volatile', 'while', 'with', 'yield'
        ];
        
        // 将关键字包装在<span>标签中
        foreach ($keywords as $keyword) {
            $code = preg_replace(
                '/\b(' . preg_quote($keyword) . ')\b/i',
                '<span class="keyword">$1</span>',
                $code
            );
        }
        
        // 字符串处理
        $code = preg_replace(
            '/(".*?")|(\'.*?\')/',
            '<span class="string">$1$2</span>',
            $code
        );
        
        // 注释处理
        $code = preg_replace(
            '/(\/\/.*$)|(\/\*.*?\*\/)/m',
            '<span class="comment">$1$2</span>',
            $code
        );
        
        return $code;
    }
    
    /**
     * HTML代码高亮
     * @param string $code HTML代码
     * @return string 高亮后的代码
     */
    private static function highlightHtml($code)
    {
        // 标签处理
        $code = preg_replace(
            '/(&lt;\/?[^&]*?&gt;)/',
            '<span class="tag">$1</span>',
            $code
        );
        
        // 属性处理
        $code = preg_replace(
            '/([a-zA-Z\-]+)=/i',
            '<span class="attribute">$1</span>=',
            $code
        );
        
        return $code;
    }
    
    /**
     * CSS代码高亮
     * @param string $code CSS代码
     * @return string 高亮后的代码
     */
    private static function highlightCss($code)
    {
        // CSS属性
        $properties = [
            'background', 'color', 'font-size', 'font-family', 'margin', 'padding', 'border',
            'width', 'height', 'display', 'position', 'top', 'left', 'right', 'bottom', 'float',
            'clear', 'overflow', 'visibility', 'z-index', 'opacity', 'cursor', 'text-align',
            'text-decoration', 'text-transform', 'line-height', 'letter-spacing', 'word-spacing',
            'white-space', 'vertical-align', 'list-style', 'background-color', 'border-color',
            'border-width', 'border-style', 'margin-top', 'margin-right', 'margin-bottom',
            'margin-left', 'padding-top', 'padding-right', 'padding-bottom', 'padding-left'
        ];
        
        // 将CSS属性包装在<span>标签中
        foreach ($properties as $property) {
            $code = preg_replace(
                '/\b(' . preg_quote($property) . ')\s*:/i',
                '<span class="property">$1</span>:',
                $code
            );
        }
        
        // CSS值处理
        $code = preg_replace(
            '/:\s*([^;]+);/',
            ': <span class="value">$1</span>;',
            $code
        );
        
        // 选择器处理
        $code = preg_replace(
            '/^([^{]+)\s*\{/m',
            '<span class="selector">$1</span> {',
            $code
        );
        
        return $code;
    }
    
    /**
     * Python代码高亮
     * @param string $code Python代码
     * @return string 高亮后的代码
     */
    private static function highlightPython($code)
    {
        // Python关键字
        $keywords = [
            'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else',
            'except', 'exec', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is',
            'lambda', 'not', 'or', 'pass', 'print', 'raise', 'return', 'try', 'while', 'with',
            'yield', 'None', 'True', 'False'
        ];
        
        // 将关键字包装在<span>标签中
        foreach ($keywords as $keyword) {
            $code = preg_replace(
                '/\b(' . preg_quote($keyword) . ')\b/i',
                '<span class="keyword">$1</span>',
                $code
            );
        }
        
        // 字符串处理
        $code = preg_replace(
            '/(".*?")|(\'.*?\')/',
            '<span class="string">$1$2</span>',
            $code
        );
        
        // 注释处理
        $code = preg_replace(
            '/(#.*$)/m',
            '<span class="comment">$1</span>',
            $code
        );
        
        return $code;
    }
}